package com.shanghaionstar.login.register.service;

import android.content.Context;
import android.text.TextUtils;
import android.util.SparseArray;

import com.onstar.cn.api.JoinmeInfo3Service;
import com.onstar.cn.api.JoinmeService;
import com.onstar.cn.api.v3.JoinMeVehicle;
import com.onstar.cn.common.exception.HttpException;
import com.onstar.cn.common.exception.OnStarException;
import com.onstar.cn.common.util.CommonUtil;
import com.onstar.cn.common.util.Constants;
import com.onstar.cn.common.util.DeviceUtil;

import com.onstar.cn.framework.annotation.http.HeadsValue;
import com.onstar.cn.framework.annotation.http.Request;
import com.onstar.cn.framework.mvp.base.core.BaseService;
import com.onstar.cn.framework.network.HttpInjectUtils;
import com.onstar.cn.framework.network.entity.RequestEntity;
import com.onstar.cn.framework.network.enumtype.HttpAccept;
import com.onstar.cn.framework.network.enumtype.HttpMethod;
import com.onstar.cn.framework.network.enumtype.Language;
import com.onstar.cn.framework.network.http.CommonError;
import com.onstar.cn.framework.utils.GsonHelper;
import com.onstar.cn.mag.enumtype.SendCodeSenarioType;
import com.onstar.cn.mag.joinme.CatpchaEntity;
import com.onstar.cn.mag.joinme.RegisterRequestEntity;
import com.onstar.cn.mag.joinme.RegisterResponseEntity;
import com.onstar.cn.mag.joinme.RegisterToVisitorResponse;
import com.onstar.cn.vehicle.entity.ErrorInfo;
import com.shanghaionstar.utils.ApplicationUtil;
import com.shanghaionstar.utils.BusinessUtil;
import com.shanghaionstar.utils.ErrorCodeUtil;
import com.shanghaionstar.utils.FinalConstants;
import com.shanghaionstar.utils.JoinMeConstants;
import com.shanghaionstar.utils.NetConnectUtil;

import java.util.LinkedHashMap;
import java.util.Locale;

import rx.Observable;
import rx.Subscriber;
import rx.functions.Func0;

/**
 * Created by 7828wc on 16/7/1.
 */
public class JoinMeService extends BaseService<RegisterResponseEntity> {
    private Context context;

    public JoinMeService(Context context) {
        this.context = context;
    }

    private RequestEntity requestEntity;

    @Override
    public RequestEntity getRequestEntity() {
        return requestEntity;
    }

    @Override
    public RegisterResponseEntity jsonToBean(String json) {
        return GsonHelper.fromJson( json,RegisterResponseEntity.class);
    }

    @Request(heads = @HeadsValue(accept = HttpAccept.JSON, language = Language.AUTO), method = HttpMethod.GET)
    public Observable<CatpchaEntity> checkIsNeedCaptcha(final CatpchaEntity cacheCatpcha) {
        return Observable.defer(new Func0<Observable<CatpchaEntity>>() {
            @Override
            public Observable<CatpchaEntity> call() {
                try {
//                    供缓存使用
//                    if (cacheCatpcha != null) {
//                        return Observable.just((cacheCatpcha));
//                    } else {
                    JoinmeService joinmeService = new JoinmeService(Constants.CURRENT_SERVER_URL);
                    RequestEntity requestEntity = NetConnectUtil.getAuthRequestEntity(context);
                    LinkedHashMap<String, Object> coHashMap = new LinkedHashMap<String, Object>();
                    coHashMap.put(FinalConstants.HTTP_AUTHORIZATION, ApplicationUtil.getInstance().getToken());
                    coHashMap.put(FinalConstants.DEVICE_ID, new DeviceUtil(context).getDeviceID());
                    requestEntity.setCustomHeads(coHashMap);
                    requestEntity = joinmeService.checkIsNeedInputCaptcha(requestEntity);

                    requestEntity = HttpInjectUtils.injectHttp(JoinMeService.this.getClass(), "checkIsNeedCaptcha", requestEntity, CatpchaEntity.class);
                    return Observable.just( GsonHelper.fromJson( getResponse(getDatas(requestEntity)),CatpchaEntity.class));
//                    }
                } catch (OnStarException e) {
                    return Observable.error(e);
                }
            }
        });
    }

    @Request(heads = @HeadsValue(accept = HttpAccept.JSON, language = Language.AUTO), method = HttpMethod.GET)
    public Observable<Object> getImageCaptcha(final String captchaId) {
        return Observable.defer(new Func0<Observable<Object>>() {
            @Override
            public Observable<Object> call() {
                try {
                    JoinmeService joinmeService = new JoinmeService(Constants.CURRENT_SERVER_URL);
                    RequestEntity requestEntity = NetConnectUtil.getAuthRequestEntity(context);
                    LinkedHashMap<String, Object> coHashMap = new LinkedHashMap<String, Object>();
                    coHashMap.put(FinalConstants.HTTP_AUTHORIZATION, ApplicationUtil.getInstance().getToken());
                    coHashMap.put(FinalConstants.DEVICE_ID, new DeviceUtil(context).getDeviceID());
                    requestEntity.setCustomHeads(coHashMap);
                    requestEntity.setByteResponse(true);
                    requestEntity = joinmeService.getImageCaptcha(requestEntity, captchaId);

                    requestEntity = HttpInjectUtils.injectHttp(JoinMeService.this.getClass(), "getImageCaptcha", requestEntity, String.class);
                    return Observable.just(getResponseByObject(getDatasByByte(requestEntity)));
                } catch (OnStarException e) {
                    return Observable.error(e);
                }
            }
        });
    }

    @Request(heads = @HeadsValue(accept = HttpAccept.JSON, language = Language.AUTO), method = HttpMethod.GET)
    public Observable<String> checkImageCaptcha(final String captchaId, final String captchaValue) {
        return Observable.defer(new Func0<Observable<String>>() {
            @Override
            public Observable<String> call() {
                try {
                    JoinmeService joinmeService = new JoinmeService(Constants.CURRENT_SERVER_URL);
                    RequestEntity requestEntity = NetConnectUtil.getAuthRequestEntity(context);
                    LinkedHashMap<String, Object> coHashMap = new LinkedHashMap<String, Object>();
                    coHashMap.put(FinalConstants.HTTP_AUTHORIZATION, ApplicationUtil.getInstance().getToken());
                    coHashMap.put(FinalConstants.DEVICE_ID, new DeviceUtil(context).getDeviceID());
                    requestEntity.setCustomHeads(coHashMap);
                    requestEntity = joinmeService.checkIsCaptchaValue(requestEntity, captchaId, captchaValue);
                    requestEntity = HttpInjectUtils.injectHttp(JoinMeService.this.getClass(), "checkImageCaptcha", requestEntity, String.class, String.class);
                    return Observable.just(getResponse(getDatas(requestEntity)));
                } catch (OnStarException e) {
                    return Observable.error(e);
                }
            }
        });
    }

    @Request(heads = @HeadsValue(accept = HttpAccept.JSON, language = Language.AUTO), method = HttpMethod.GET)
    public Observable<String> getVehicleUnit(final String vin) {
        return Observable.defer(new Func0<Observable<String>>() {
            @Override
            public Observable<String> call() {
                try {
                    JoinMeVehicle vehicleService = new JoinMeVehicle(Constants.CURRENT_SERVER_URL);
                    RequestEntity requestEntity = NetConnectUtil.getAuthRequestEntity(context);
                    LinkedHashMap<String, Object> coHashMap = new LinkedHashMap<String, Object>();
                    coHashMap.put(FinalConstants.HTTP_AUTHORIZATION, ApplicationUtil.getInstance().getToken());
                    coHashMap.put(FinalConstants.DEVICE_ID, new DeviceUtil(context).getDeviceID());
                    requestEntity.setCustomHeads(coHashMap);
                    requestEntity = vehicleService.getVehicleUnit(requestEntity, vin);
                    requestEntity = HttpInjectUtils.injectHttp(JoinMeService.this.getClass(), "getVehicleUnit", requestEntity, String.class);
                    return Observable.just(getResponse(getDatas(requestEntity)));
                } catch (OnStarException e) {
                    return Observable.error(e);
                }
            }
        });
    }

    @Request(heads = @HeadsValue(accept = HttpAccept.JSON, language = Language.AUTO), method = HttpMethod.PUT)
    public Observable<RegisterResponseEntity> registerOwner(final CatpchaEntity catpchaEntity, final String governmentId, final String vin, final JoinMeConstants.OperationType operationType, final String... otherParams) {
        return Observable.defer(new Func0<Observable<RegisterResponseEntity>>() {
            @Override
            public Observable<RegisterResponseEntity> call() {
                try {
//                    JoinmeService joinmeService = new JoinmeService(Constants.CURRENT_SERVER_URL);
                    JoinmeInfo3Service joinmeService = new JoinmeInfo3Service(Constants.CURRENT_SERVER_URL);
                    RequestEntity requestEntity = NetConnectUtil.getAuthRequestEntity(context);

                    RegisterRequestEntity registerRequestEntity = new RegisterRequestEntity();
                    registerRequestEntity.setGovernmentID(governmentId);
                    registerRequestEntity.setVin(vin);
                    registerRequestEntity.setSourceId(new DeviceUtil(context).getDeviceID());
                    registerRequestEntity.setSendCodeSenario(SendCodeSenarioType.REG_SUBSCRIBER.value());
                    LinkedHashMap<String, Object> coHashMap = new LinkedHashMap<String, Object>();
                    coHashMap.put(FinalConstants.HTTP_AUTHORIZATION, ApplicationUtil.getInstance().getToken());
                    if (catpchaEntity != null && catpchaEntity.isRequired()) {
                        registerRequestEntity.setCaptchaId(!CommonUtil.isNull(catpchaEntity.getCaptchaId()) ? catpchaEntity.getCaptchaId() : "");
                        registerRequestEntity.setCaptchaValue(!CommonUtil.isNull(catpchaEntity.getCaptchaInput()) ? catpchaEntity.getCaptchaInput() : "");
                        coHashMap.put(FinalConstants.DEVICE_ID, new DeviceUtil(context).getDeviceID());
                    }

                    if (otherParams != null && otherParams.length >= 1) {
                        if (!CommonUtil.isNull(otherParams[0])) {
                            registerRequestEntity.setSecCode(otherParams[0]);
                        }
                        if (!CommonUtil.isNull(otherParams[1])) {
                            registerRequestEntity.setPassWord(otherParams[1]);
                        }
//                        if(!CommonUtil.isNull(otherParams[2])){
//                            registerRequestEntity.setSecCode(otherParams[2]);
//                        }
                        if (!CommonUtil.isNull(otherParams[2])) {
                            registerRequestEntity.setMobilePhoneNumber(otherParams[2]);
                            registerRequestEntity.setEmailAddress("");
                        }
                        if (!CommonUtil.isNull(otherParams[3])) {
                            registerRequestEntity.setEmailAddress(otherParams[3]);
                            registerRequestEntity.setMobilePhoneNumber("");
                            registerRequestEntity.setDestType("E");
                        }
                        if (!CommonUtil.isNull(otherParams[4])) {
                            registerRequestEntity.setFirstName(otherParams[4]);
                        }
                        if (!CommonUtil.isNull(otherParams[5])) {
                            registerRequestEntity.setLastName(otherParams[5]);
                        }
                    }
                    requestEntity.setCustomHeads(coHashMap);
                    if (operationType == JoinMeConstants.OperationType.CHECKREGCODE) {
//                       JoinmeService service = new com.onstar.cn.api.v2.JoinmeService(Constants.CURRENT_SERVER_URL);
                        requestEntity = joinmeService.registerToSubscriber(requestEntity, registerRequestEntity);
                    } else {
                        requestEntity = joinmeService.registerCode(requestEntity, registerRequestEntity);
                    }
                    requestEntity = HttpInjectUtils.getDefaultConfig(Language.AUTO, HttpMethod.PUT, HttpAccept.JSON, requestEntity);
//                    requestEntity = HttpInjectUtils.injectHttp(JoinMeService.this.getClass(), "registerOwner", requestEntity, CatpchaEntity.class, String.class, String.class, JoinMeConstants.OperationType.class);
                    return Observable.just((RegisterResponseEntity) GsonHelper.fromJson( getResponse(getDatas(requestEntity)),RegisterResponseEntity.class));
                } catch (OnStarException e) {
                    return Observable.error(e);
                }
            }
        });
    }

    @Request(heads = @HeadsValue(accept = HttpAccept.JSON, language = Language.AUTO), method = HttpMethod.PUT)
    public Observable<RegisterToVisitorResponse> visitorCheckAndUpgrade(final CatpchaEntity catpchaEntity, final String governmentId, final String vin, final boolean isCheckVisitor, final String... args) {
        return Observable.defer(new Func0<Observable<RegisterToVisitorResponse>>() {
            @Override
            public Observable<RegisterToVisitorResponse> call() {
                try {
//                    JoinmeService joinmeService = new JoinmeService(Constants.CURRENT_SERVER_URL);
                    JoinmeInfo3Service joinmeService1 = new JoinmeInfo3Service(Constants.CURRENT_SERVER_URL);
                    RequestEntity requestEntity = NetConnectUtil.getAuthRequestEntity(context);

                    RegisterRequestEntity registerRequestEntity = new RegisterRequestEntity();
                    //****************升级为车主这段逻辑耦合太严重，需要重构，现在不得不冒风险注释掉以下，以让1-2最后一步能够设置带有govid的body***********************//
//                    if (!isCheckVisitor) {
                    registerRequestEntity.setGovernmentID(governmentId);
                    registerRequestEntity.setVin(vin);
//                    }
                    //****************升级为车主这段逻辑耦合太严重，需要重构，现在不得不冒风险注释掉以下，以让1-2最后一步能够设置带有govid的body***********************//
                    registerRequestEntity.setUserName(ApplicationUtil.getInstance().getIdpID());
                    registerRequestEntity.setLanguageId(DeviceUtil.getLanguage().toUpperCase(Locale.CHINA).equals("ZH") ? "CN" : DeviceUtil.getLanguage()
                            .toUpperCase(Locale.CHINA));
                    registerRequestEntity.setSourceId(new DeviceUtil(context).getDeviceID());
                    registerRequestEntity.setUserName(ApplicationUtil.getInstance().getIdpID());
                    registerRequestEntity.setSendCodeSenario(SendCodeSenarioType.SUB_TO_VISITOR.value());
                    if (args != null && args.length > 0 && !TextUtils.isEmpty(args[0])) {
                        registerRequestEntity.setFirstName(args[0]);
                        registerRequestEntity.setLastName(args[1]);
                    }
                    if (!CommonUtil.isNull(catpchaEntity) && catpchaEntity.isRequired()) {
                        registerRequestEntity.setCaptchaId(!CommonUtil.isNull(catpchaEntity.getCaptchaId()) ? catpchaEntity.getCaptchaId() : "");
                        registerRequestEntity.setCaptchaValue(!CommonUtil.isNull(catpchaEntity.getCaptchaInput()) ? catpchaEntity.getCaptchaInput() : "");
                    }
                    LinkedHashMap<String, Object> coHashMap = new LinkedHashMap<String, Object>();
                    coHashMap.put(FinalConstants.HTTP_AUTHORIZATION, ApplicationUtil.getInstance().getToken());
                    coHashMap.put(FinalConstants.DEVICE_ID, new DeviceUtil(context).getDeviceID());
                    requestEntity.setCustomHeads(coHashMap);
                    requestEntity.setBody(GsonHelper.toJson(registerRequestEntity));
                    requestEntity = isCheckVisitor ? joinmeService1.registerToUpgrade(requestEntity, registerRequestEntity) : joinmeService1.registerCode(requestEntity, registerRequestEntity);

                    requestEntity = HttpInjectUtils.injectHttp(JoinMeService.this.getClass(), "visitorCheckAndUpgrade", requestEntity, CatpchaEntity.class, String.class, String.class, boolean.class,String[].class);
                    return Observable.just( GsonHelper.fromJson( getResponse(getDatas(requestEntity)),RegisterToVisitorResponse.class));
                } catch (OnStarException e) {
                    return Observable.error(e);
                }
            }
        });
    }

    @Request(heads = @HeadsValue(accept = HttpAccept.JSON, language = Language.AUTO), method = HttpMethod.PUT)
    public void registerVisitor(final RegisterRequestEntity registerRequestEntity, final String operationType) {
        JoinmeService joinmeService = new JoinmeService(Constants.CURRENT_SERVER_URL);
        JoinmeInfo3Service joinmeService1 = new JoinmeInfo3Service(Constants.CURRENT_SERVER_URL);
        requestEntity = NetConnectUtil.getAuthRequestEntity(context);
        registerRequestEntity.setSourceId(new DeviceUtil(context).getDeviceID());
        registerRequestEntity.setSendCodeSenario(SendCodeSenarioType.REG_VISITOR.value());

        if (!CommonUtil.isNull(operationType) && operationType.equalsIgnoreCase(JoinMeConstants.OperationType.INVOKEREGCODE.getOperationType())) {
            requestEntity = joinmeService1.registerCode(requestEntity, registerRequestEntity);
        } else if (!CommonUtil.isNull(operationType) && operationType.equalsIgnoreCase(JoinMeConstants.OperationType.CHECKREGCODE.getOperationType())) {
            requestEntity = joinmeService1.registerToVisitor(requestEntity, registerRequestEntity);
        } else {
            requestEntity = joinmeService.registercheckUnique(requestEntity, registerRequestEntity);
        }

        requestEntity = HttpInjectUtils.injectHttp(JoinMeService.this.getClass(), "registerVisitor", requestEntity, RegisterRequestEntity.class, String.class);
    }

    public Observable<RegisterResponseEntity> registerVisitorCheckUnique(final RegisterRequestEntity registerRequestEntity) {
        return Observable.create(new Observable.OnSubscribe<RegisterResponseEntity>() {
            @Override
            public void call(Subscriber<? super RegisterResponseEntity> subscriber) {
                try {
                    registerVisitor(registerRequestEntity, JoinMeConstants.OperationType.CHECKUNIQUE.getOperationType());
                    RegisterResponseEntity response = GsonHelper.fromJson( getResponse(getDatas(requestEntity)),RegisterResponseEntity.class);
                    if (registerRequestEntity != null) {
                        if (!CommonUtil.isNull(registerRequestEntity.getUserName())) {
                            response.setUserName(registerRequestEntity.getUserName());
                        } else {
                            response.setIsUserNameUnique("");
                        }

                        if (!CommonUtil.isNull(registerRequestEntity.getEmailAddress())) {
                            response.setEmailAddress(registerRequestEntity.getEmailAddress());
                        } else {
                            response.setIsEmailUnique("");
                        }

                        if (!CommonUtil.isNull(registerRequestEntity.getMobilePhoneNumber())) {
                            response.setMobilePhoneNumber(registerRequestEntity.getMobilePhoneNumber());
                        } else {
                            response.setIsMobileUnique("");
                        }
                    }
                    subscriber.onNext(response);
                    subscriber.onCompleted();
                } catch (OnStarException e) {
                    subscriber.onError(e);
                }
            }
        });
    }

    private String getResponse(SparseArray<String> reseponseData) throws OnStarException {
        if (reseponseData != null && reseponseData.size() != 0) {
            int responseCode = -1;
//            for (Integer key : reseponseData.keySet()) {
//                responseCode = key;
//                break;
//            }
            for(int i=0;i<reseponseData.size();i++) {
                responseCode = reseponseData.keyAt(i);
                break;
            }
            if (responseCode != 200 && responseCode != 202) {
                CommonError commonError = GsonHelper.fromJson( reseponseData.get(responseCode),CommonError.class);
                HttpException httpException = new HttpException(commonError.getErrorCode(), commonError.getErrorMessage());
                ErrorInfo errorInfo = ErrorCodeUtil.getErrorInfoByHttpException(context, httpException);
                throw new HttpException(errorInfo.getCode(), errorInfo.getMsg());
            } else {
                return reseponseData.get(responseCode);
            }
        }
        return null;
    }

    private Object getResponseByObject(SparseArray<Object> reseponseData) throws OnStarException {
        if (reseponseData != null && reseponseData.size() != 0) {
            int responseCode = -1;
//            for (Integer key : reseponseData.keySet()) {
//                responseCode = key;
//                break;
//            }
            for (int i = 0; i < reseponseData.size(); i++) {
                responseCode = reseponseData.keyAt(i);
                break;
            }
            if (responseCode != 200 && responseCode != 202) {
                CommonError commonError = GsonHelper.fromJson((String) reseponseData.get(responseCode),CommonError.class);
                HttpException httpException = new HttpException(commonError.getErrorCode(), commonError.getErrorMessage());
                ErrorInfo errorInfo = ErrorCodeUtil.getErrorInfoByHttpException(context, httpException);
                throw new HttpException(errorInfo.getCode(), errorInfo.getMsg());
            } else {
                return reseponseData.get(responseCode);
            }
        }
        return null;
    }


}